package com.mynetwork.gcm;


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;

import org.apache.http.conn.ConnectTimeoutException;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.android.gcm.GCMRegistrar;
import com.mynetwork.data.NetworkManager;
import com.mynetwork.data.OnNetworkListener;
import com.mynetwork.data.StatisticsManager;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.StrictMode;
import android.text.TextUtils;
import android.util.Log;

/**
 * @brief [설정] gcm 푸시 알림 매니저 클래스
 * @author PiaJang
 */
public class GCMManager {
	private static final String TAG = "GCMManager";
	
	public static String PROJECT_ID = "904462265993"; //서버에서 받아야 하는 프로젝트 ID
	public static String APIKEY = "AIzaSyBv-0DYR8hvRAwTGyI3QjPqUa_RGFxWMBo"; // 서버에서 전송시 필요한 apikey
	public static String NOTI_ACTION_NAME = "com.mediastory.Audi.noti.broadcast";
	public static String GCM_BROADCAST_ACTION = "com.mediastory.Audi.gcm.GCMIntentService";
	
	
	/**
	 * 상단 푸시알림
	 */
	public final static String GCM_NOTI_STATE = "noti_state"; //상단 노티 NotiBR 호출시
	public final static String GCM_NOTI_STATE_DELETED = "noti_deleted"; //NOTI_STATE 의 값
	public final static String GCM_NOTI_STATE_CLICKED = "noti_clicked"; //NOTI_STATE 의 값
	public final static String GCM_NOTI_ID = "noti_id";
	
	public static GCMManager m_gcmMgr = null;
	
	public static boolean isRegistration = false;
	
	private Context m_ctx = null;
	
	public static GCMManager getInstance() {
		if (m_gcmMgr == null) {
			synchronized (GCMManager.class) {
				m_gcmMgr = new GCMManager();
			}
		}
		return m_gcmMgr;
	}
	
	/**
	 * @brief 초기화 (호출 필수)
	 * @param ctx
	 */
	public void InitGCMMgr(Context ctx){
		m_ctx = ctx;
		GCMRegistrar.checkDevice(ctx);
		GCMRegistrar.checkManifest(ctx);
	}
	
	/**
	 * @param ctx
	 * @return RegistrationID (등록된 ID값 반환 - 서버에 전송해야 하는 값)
	 */
	public String getGCMRegistrationId(Context ctx){
		return GCMRegistrar.getRegistrationId(ctx);
	}

	/**
	 * @brief GCM 등록
	 */
	public void GCMRegister() {
		if(m_ctx == null || TextUtils.isEmpty(PROJECT_ID)) return;
		
		isRegistration = false;
		
		if("".equals(getGCMRegistrationId(m_ctx))){
			 GCMRegistrar.register(m_ctx, PROJECT_ID);
		} else {
			 GCMRegistrar.unregister(m_ctx);
			 GCMRegistrar.register(m_ctx, PROJECT_ID);
		}		
	}
	
	/**
	 * @brief GCM 등록해제!!
	 */
	public void GCMUnregister(){
		if(!("".equals(getGCMRegistrationId(m_ctx))))
			GCMRegistrar.unregister(m_ctx);
	}
	
	//[[ GCM Network ---------------------------------------------------------------------------
	public OnNetworkListener mOnNetworkListener;
	
	public void setGCMStatus(String auth_key, boolean isRegistration, OnNetworkListener l) {
		mOnNetworkListener = l;
		new ProductDownloadAsyncTask(auth_key).execute();
	}
	
    private class ProductDownloadAsyncTask extends AsyncTask<Object, Object, Boolean> {
    	private String mKey;
    	public ProductDownloadAsyncTask(String key) {
    		mKey = key;
    	}
		@Override
		protected Boolean doInBackground(Object... params) {
			HttpURLConnection conn = null;
			try {
				URL url = new URL(NetworkManager.getApiServerURL() + NetworkManager.GCM_REGISTER);
				conn = (HttpURLConnection) url.openConnection();
				conn.setDoInput(true);
				conn.setDoOutput(true);
				conn.setRequestMethod("POST");
				conn.setConnectTimeout(5000);
				conn.setAllowUserInteraction(true);
				conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
				conn.addRequestProperty("Accept", "application/json");

				StringBuilder strBuilder = NetworkManager.getNetworkDefaultPacket();
				strBuilder.append("&key=" + mKey);
				Log.e(TAG,"KDS3393_url = " + NetworkManager.getApiServerURL() + NetworkManager.GCM_REGISTER + strBuilder.toString());
				OutputStreamWriter outStream = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); 
	            PrintWriter writer = new PrintWriter(outStream); 
	            writer.write(strBuilder.toString()); 
	            writer.flush(); 

	            InputStreamReader tmp = new InputStreamReader(conn.getInputStream(), "UTF-8");  
	            BufferedReader reader = new BufferedReader(tmp); 
	            StringBuilder builder = new StringBuilder(); 
	            String str; 
	            while ((str = reader.readLine()) != null) {       // 서버에서 라인단위로 보내줄 것이므로 라인단위로 읽는다 
	                builder.append(str + "\n");                     // View에 표시하기 위해 라인 구분자 추가 
	            } 
	            
	            tmp.close();
	            
				JSONObject jsonObj = new JSONObject(builder.toString());
				
				if (jsonObj.getInt("returnCode") != 0)
					return false;
				
			} catch (SocketTimeoutException e) {
 				Log.e(TAG,"Error : SocketTimeoutException");
 				return false;
 			} catch (ConnectTimeoutException e) {
 				Log.e(TAG,"Error : ConnectTimeoutException");
 				return false;
 			} catch (Exception e) {
 				Log.e(TAG,""+e);
				if(conn != null){
					conn.disconnect();
					conn = null;
				}
				return false;
			}
 			return true;
 		}
 		
 		@Override
 		protected void onPostExecute(Boolean result) {
 			if (mOnNetworkListener != null) {
 				if (result) {
 					mOnNetworkListener.onSuccess(null);
 				} else {
 					mOnNetworkListener.onError(null);
 				}
 			}
 		}
    }
    
    
    //[[ SharedPreferences -------------------------------------------------------------------------------- 
    public final static String INI_FILENAME_CONFIG = "push_config";
    
	// 노티 공지사항 관련 설정
    public final static String CONFIG_SETTINGS_PUSH = "settings_push";			// 푸시알림설정 여부
	public final static String CONFIG_NOTI_COUNT = "noti_count";	// 상단 노티 누적 개수
	
	/**
	 * @brief 설정의 푸시알림 설정정보 읽기
	 * @param _ctx
	 * @return 설정 값 반환
	 */
	public static boolean getSettingsPush(Context _ctx){
		SharedPreferences pref = _ctx.getSharedPreferences(INI_FILENAME_CONFIG, 0);
		return pref.getBoolean(CONFIG_SETTINGS_PUSH, true);
	}
	
	/**
	 * @brief	설정의 푸시알림정보 설정
	 * @param _ctx
	 * @param bIsSet 알림 설정 (on/off)
	 */
	public static void setSettingsPush(Context _ctx, boolean bIsSet){
		try {
			StatisticsManager.setSetupPush(bIsSet);
		} catch (Exception e) {
			Log.e(TAG, "" + e);
		}
		SharedPreferences pref = _ctx.getSharedPreferences(INI_FILENAME_CONFIG, 0);
		SharedPreferences.Editor edit = pref.edit();
		edit.putBoolean(CONFIG_SETTINGS_PUSH, bIsSet);
		edit.commit();
	}
	
	/**
	 * @brief 상단 노티 누적 개수 설정
	 * @param _ctx
	 * @param nNotiCount 상단 노티 개수
	 */
	public static void setNotiCount(Context _ctx, int nNotiCount){
		SharedPreferences pref = _ctx.getSharedPreferences(INI_FILENAME_CONFIG, 0);
		SharedPreferences.Editor edit = pref.edit();
		edit.putInt(CONFIG_NOTI_COUNT, nNotiCount);
		edit.commit();
	}
	
	/**
	 * @brief 상단 노티 누적 개수 읽기
	 * @param _ctx
	 * @return
	 */
	public static int getNotiCount(Context _ctx){
		SharedPreferences pref = _ctx.getSharedPreferences(INI_FILENAME_CONFIG, 0);
		return pref.getInt(CONFIG_NOTI_COUNT, 0);
	}
}
